package secondriver.aboxlibrary.utils;

import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Build;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

/**
 * Author : secondriver
 * Created : 2015/12/8
 */
public class BitmapUtil {

    /**
     * http://stackoverflow.com/questions/4349075/bitmapfactory-decoderesource-returns-a-mutable-bitmap-in-android-2-2-and-an-immu
     */

    /**
     * decodes a bitmap from a resource id. returns a mutable bitmap no matter what is the API level.<br/>
     * might use the internal storage in some cases, creating temporary file that will be deleted as soon as it isn't finished
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static Bitmap decodeMutableBitmapFromResourceId(final Context context, final int bitmapResId) {
        final BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
            bitmapOptions.inMutable = true;
        }
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), bitmapResId, bitmapOptions);
        if (!bitmap.isMutable()) {
            bitmap = convertToMutable(context, bitmap);
        }
        return bitmap;
    }

    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    public static Bitmap convertToMutable(final Context context, final Bitmap imgIn) {
        final int width = imgIn.getWidth();
        final int height = imgIn.getHeight();
        final Bitmap.Config type = imgIn.getConfig();
        File outputFile = null;
        final File outputDir = context.getCacheDir();
        try {
            outputFile = File.createTempFile(Long.toString(System.currentTimeMillis()), null, outputDir);
            outputFile.deleteOnExit();
            final RandomAccessFile randomAccessFile = new RandomAccessFile(outputFile, "rw");
            final FileChannel channel = randomAccessFile.getChannel();
            final MappedByteBuffer map = channel.map(FileChannel.MapMode.READ_WRITE, 0, imgIn.getRowBytes() * height);
            imgIn.copyPixelsToBuffer(map);
            imgIn.recycle();
            final Bitmap result = Bitmap.createBitmap(width, height, type);
            map.position(0);
            result.copyPixelsFromBuffer(map);
            channel.close();
            randomAccessFile.close();
            outputFile.delete();
            return result;
        } catch (final Exception e) {
        } finally {
            if (outputFile != null)
                outputFile.delete();
        }
        return null;
    }


    /**
     * 旋转Bitmap
     *
     * @param src
     * @param rotateDegrees
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap src, float rotateDegrees) {
        Matrix m = new Matrix();
        m.postRotate(rotateDegrees);
        Bitmap dest = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), m, false);
        return dest;
    }

    /**
     * 设置图片压缩Options
     *
     * @param options
     * @param reqWidth  压缩后的宽
     * @param reqHeight 压缩后的高
     */
    public static void inSampleSize(final BitmapFactory.Options options, int reqWidth, int reqHeight) {
        final int outWidth = options.outWidth;
        final int outHeight = options.outHeight;
        int inSampleSize = 1;
        if (outWidth > reqWidth || outHeight > reqHeight) {
            int widthScaleRatio = Math.round(outWidth / reqWidth);
            int heightScaleRatio = Math.round(outHeight / reqHeight);
            inSampleSize = widthScaleRatio < heightScaleRatio ? widthScaleRatio : heightScaleRatio;
        }
        options.inSampleSize = inSampleSize;
        options.inJustDecodeBounds = false;
    }

    /**
     * Bitmap按要求尺寸缩放
     *
     * @param src
     * @param reqWidth  缩放后的宽
     * @param reqHeight 缩放后的高
     * @return 缩放后的Bitmap
     */
    public static Bitmap scale(Bitmap src, int reqWidth, int reqHeight) {
        final int width = src.getWidth();
        final int height = src.getHeight();
        float widthScaleRatio = (float) (width / reqWidth);
        float heightScaleRatio = (float) (height / reqHeight);
        Matrix matrix = new Matrix();
        matrix.setScale(widthScaleRatio, heightScaleRatio);
        return Bitmap.createBitmap(src, 0, 0, width, height, matrix, true);
    }

    /**
     * 压缩Bitmap
     *
     * @param src
     * @param maxSize 压缩后的最大字节数单位kb
     */
    public static void compress(Bitmap src, double maxSize) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        src.compress(Bitmap.CompressFormat.JPEG, 100, bos);
        byte[] bytes = bos.toByteArray();
        double mbBytes = bytes.length / 1024;
        int times = (int) (mbBytes / maxSize);
        if (times > 1) {
            double scale = Math.sqrt(times);
            BitmapUtil.scale(src, (int) (src.getWidth() / scale), (int) (src.getHeight() / scale));
        }
    }
}